<?php


namespace App\Order\Service\Order;


use App\Common\Constants\ErrorCode;
use App\Common\Constants\Stakeholder;
use App\Common\Job\LogJob;
use App\Common\Service\BaseService;
use App\Common\Service\Random;
use App\Order\Event\CreateActivityOrder;
use App\Order\Event\CreateShopOrder;
use App\Order\Job\CancelOrderJob;
use App\Order\Model\OrderGoodsModel;
use App\Order\Model\OrderModel;
use App\Order\Service\Entrust\EntrustMiniService;
use App\Order\Service\OrderGoodsService;
use App\Resource\Model\GoodsModel;
use App\Resource\Model\ShopModel;
use App\Resource\Service\Cart\CartMiniService;
use App\Resource\Service\ShopService;
use App\Resource\Service\SystemService;
use App\Resource\Service\CartService;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Contract\LengthAwarePaginatorInterface;
use App\Order\Repository\RepositoryFactory;

class OrderBaseService extends BaseService
{

    /**
     * @Inject()
     * @var CartService
     */
    protected $cartService;

    /**
     * @Inject()
     * @var CartMiniService
     */
    protected $cartMiniService;

    /**
     * @Inject()
     * @var EntrustMiniService
     */
    protected $entrustMiniService;
    /**
     * @Inject()
     * @var SystemService
     */
    protected $systemService;


    const SHOP_GOODS_SHELVE = 'shopGoodsShelve:shopSelfNum';
    /**
     * 送货方式：(1配送订单,2为自提订单)
     */
    const ORDER_DEAL_TYPE_1 = 1;
    const ORDER_DEAL_TYPE_2 = 2;
    /**
     * 订单类型(0 普通订单   2、普通自提订单  6 团购自提订单 7接龙订单 8次日达精选 9 次日达秒杀订单,10 免单订单)
     */
    const ORDER_TYPE_0 = 0;
    const ORDER_TYPE_2 = 2;
    const ORDER_TYPE_6 = 6;
    const ORDER_TYPE_7 = 7;
    const ORDER_TYPE_8 = 8;
    const ORDER_TYPE_9 = 9;
    const ORDER_TYPE_10 = 10;
    /**
     * 订单类别区分 0及时达、1次日达订单
     */
    const ORDER_SOURCE_0 = 0;
    const ORDER_SOURCE_1 = 1;
    /**
     * 购物车商品类型 1及时达、2次日达
     */
    const CART_SOURCE_1 = 1;
    const CART_SOURCE_2 = 2;

    /**
     * 自提订单发货状态 0 普通订单   1、自提订单未发货  2 自提订单发货状态
     */
    const ORDER_TYPE_STATUS_0 =0;
    const ORDER_TYPE_STATUS_1 =1;
    const ORDER_TYPE_STATUS_2 =2;
    /**
     * 1其他订单 2团长订单 3代客单
     */
    const PLATFORM_TYPE_1=1;
    const PLATFORM_TYPE_2=2;
    const PLATFORM_TYPE_3=3;
    /**
     * 订单支付状态： 0：未支付  1：已支付
     */
    const ORDER_IS_PAY_0 = 0;
    const ORDER_IS_PAY_1 = 1;

    /**
     * 1、单独购买 2、拼团购买
     */
    const ACTIVITY_TYPE_1 = 1;
    const ACTIVITY_TYPE_2 = 2;

    /**
     * 1 首次 2 二次
     */
    const FREE_NUM_1 = 1;
    const FREE_NUM_2 = 2;

    /**
     * 1邀请好友 ，2 重新激活,3 再试一次 ,4查看详情 5活动下架 6 继续邀请
     */
    const FREE_STEP_1 = 1;
    const FREE_STEP_2 = 2;
    const FREE_STEP_3 = 3;
    const FREE_STEP_4 = 4;
    const FREE_STEP_5 = 5;
    const FREE_STEP_6 = 6;
    /**
     * 订单状态(0,已取消，1.待付款,2.待发货,3.待取货,4已收货(已核销),5.已退款,6已拒绝,7待处理,8配送中)
     */
    const ORDER_STATUS_0 = 0;
    const ORDER_STATUS_1 = 1;
    const ORDER_STATUS_2 = 2;
    const ORDER_STATUS_3 = 3;
    const ORDER_STATUS_4 = 4;
    const ORDER_STATUS_5 = 5;
    const ORDER_STATUS_6 = 6;
    const ORDER_STATUS_7 = 7;
    /**
     * 15 分钟取消未支付订单
     */
    const CANCEL_ORDER_SECOND = 900;
    /**
     * POS 状态
     * 1:正常;2:反常
     * @var array|string[]
     */
    public array $posTypes = [Stakeholder::POS_STATUS_NORMAL  => '正常', Stakeholder::POS_STATUS_PERVERT => '反常'];
    /**
     * 送货方式
     * @var array|string[]
     */
    public array $deliveryMethod = [self::ORDER_DEAL_TYPE_1 => '配送', self::ORDER_DEAL_TYPE_2 => '自提'];
    /**
     * 处理状态
     * @var array|string[]
     */
    public array $handleStatus = [Stakeholder::REFUND_HANDLE_STATUS_1 => '待处理',Stakeholder::REFUND_HANDLE_STATUS_2 => '已处理'];
    /**
     * 退款状态
     * @var array|string[]
     */
    public array $refundStatus = ['申请退款', '已拒绝', '已退款',];
    /**
     * 配送订单状态列表
     * @var array|string[]
     */
    public array $deliveryOrderStatusNames = ['订单已取消', '待付款', '待发货', '待收货', '已完成', '已退款', '已驳回', '退款处理中'];
    /**
     * 自提单订单状态
     * @var array|string[]
     */
    public array $selfTakeOrderStatusName = ['订单已取消', '待付款', '待发货', '待自提', '已完成', '已退款', '已驳回', '退款处理中'];
    /**
     * 订单支付方式
     * @var array|string[]
     */
    public array $payTypes = [Stakeholder::ORDER_PAY_TYPE_WECHAT  => '微信支付', Stakeholder::ORDER_PAY_TYPE_BALANCE => '余额支付'];
    /**
     * @Inject()
     * @var OrderGoodsService
     */
    protected  $orderGoodsService;
    /**
     * Repository
     */
    protected $orderRepository;
    protected $shop;
    /**
     * OrderBaseService constructor.
     * @param RepositoryFactory $repositoryFactory
     */
    public function __construct(RepositoryFactory $repositoryFactory)
    {
        parent::__construct();
        $this->orderRepository = $repositoryFactory->getRepository("order");
        $this->shop = $repositoryFactory->getRepository("shop");
    }
    /**
     * 查询订单列表 by where
     * @param array $where
     * @param array|string[] $field
     * @return LengthAwarePaginatorInterface
     */
    public function getListResult(array $where = [], array $field = ['*'])
    {
        $where = $this->conditionWhere($where);
        $orderGoods = OrderGoodsModel::query()
            ->selectRaw('GROUP_CONCAT(goods_title) as order_goods_name,order_no')
            ->when($where['order_no'] ?? 0, function ($query, $order_no) {
                return $query->where('order_no', $order_no);
            })
            ->when($where['mid'] ?? 0, function ($query, $mid) {
                return $query->where('mid', $mid);
            })
            ->when($where['shop_id'] ?? 0, function ($query, $shop_id) {
                return $query->where('shop_id', $shop_id);
            })
            ->when($where['create_at'] ?? 0, function ($query, $create_at) {
                return $query->whereBetween('create_at', $create_at);
            })->groupBy(['order_no']);

        $order = OrderModel::query()
            ->from('store_order as order')
            ->leftJoin('store_shop as shop', 'order.shop_id', '=', 'shop.shop_id')
            ->leftJoin('store_member as member', 'order.mid', '=', 'member.mid')
            ->leftJoin('store_member_address as addr', 'order.address_id', '=', 'addr.id')
            ->select($field)
            ->joinSub($orderGoods, 'goods', function ($join) {
                $join->on('order.order_no', '=', 'goods.order_no');
            })
            ->when($where['order_no'] ?? 0, function ($query, $order_no) {
                return $query->where('order.order_no', $order_no);
            })
            ->when($where['create_at'] ?? 0, function ($query, $create_at) {
                return $query->whereBetween('order.create_at', $create_at);
            })
            ->when($where['pay_at'] ?? 0, function ($query, $pay_at) {
                return $query->whereBetween('order.pay_at', $pay_at);
            })
            ->when($where['refund_at'] ?? 0, function ($query, $refund_at) {
                return $query->whereBetween('order.refund_at', $refund_at);
            })
            ->when($where['complete_date'] ?? 0, function ($query, $complete_date) {
                return $query->whereBetween('order.complete_date', $complete_date);
            })
            ->when($where['phone'] ?? 0, function ($query, $phone) {
                return $query->where('order.order_phone', $phone);
            })
            ->when($where['shop_id'] ?? 0, function ($query, $shop_id) {
                return $query->where('order.shop_id', $shop_id);
            })
            ->when($where['pay_type'] ?? 0, function ($query, $pay_type) {
                return $query->where('order.pay_type', $pay_type);
            })
            ->when(is_numeric($where['order_type']), function ($query) use ($where) {
                return $query->where('order.order_type', $where['order_type']);
            })
            ->when(is_numeric($where['order_status']), function ($query) use ($where) {
                return $query->where('order.status', $where['order_status']);
            })
            ->when($where['mid'] ?? 0, function ($query, $mid) {
                return $query->where('order.mid', $mid);
            })
            ->when($where['goods_name'] ?? 0, function ($query, $goods_name) {
                return $query->whereRaw('INSTR(order_goods_name, ?) > 0', [$goods_name]);
            })
            ->when(is_numeric($where['order_source']), function ($query) use ($where) {
                return $query->where('order.order_source', $where['order_source']);
            })
            ->latest('create_at')
            ->when($where['perpage'] ?? 0, function ($query, $perPage) {
                return $query->paginate((int)$perPage);
            }, function ($query) {
                return $query->get();
            });

        return $order;
    }
    /**
     * 条件组合
     * @param array $where
     * @return array
     */
    public function conditionWhere(array $where)
    {
        $payAt = $where['pay_at'] ?? '';
        $createAt = $where['create_at'] ?? '';
        $refundAt = $where['refund_at'] ?? '';
        $completeDate = $where['complete_date'] ?? '';
        $where['order_source'] = $where['order_source'] ?? '';
        if (!empty($createAt) && strlen(trim($createAt)) > 23) {
            $where['create_at'] = [trim(substr($createAt, 0, 19)), trim(substr($createAt, -19))];
        }
        if (!empty($createAt) && strlen(trim($createAt)) < 24) {
            $where['create_at'] = [trim(substr($createAt, 0, 10)), trim(substr($createAt, -10))];
        }
        if (!empty($payAt) && strlen(trim($payAt)) > 23) {
            $where['pay_at'] = [trim(substr($payAt, 0, 19)), trim(substr($payAt, -19))];
        }
        if (!empty($payAt) && strlen(trim($payAt)) < 24) {
            $where['pay_at'] = [trim(substr($payAt, 0, 10)), trim(substr($payAt, -10))];
        }
        if (!empty($refundAt) && strlen(trim($refundAt)) > 23) {
            $where['refund_at'] = [trim(substr($refundAt, 0, 19)), trim(substr($refundAt, -19))];
        }
        if (!empty($refundAt) && strlen(trim($refundAt)) < 24) {
            $where['refund_at'] = [trim(substr($refundAt, 0, 10)), trim(substr($refundAt, -10))];
        }
        if (!empty($completeDate) && strlen(trim($completeDate)) > 23) {
            $where['complete_date'] = [trim(substr($completeDate, 0, 19)), trim(substr($completeDate, -19))];
        }
        if (!empty($completeDate) && strlen(trim($completeDate)) < 24) {
            $where['complete_date'] = [trim(substr($completeDate, 0, 10)), trim(substr($completeDate, -10))];
        }
        return $where;
    }

    public function findFirst(array $where = [], array $field = ['*'])
    {
        return OrderModel::query()
            ->select($field)
            ->where($where)
            ->first();
    }

    /**
     * 订单商品列表
     * @param array $where
     * @param array|string[] $field
     * @return array
     */
    public function goodsResult(array $where = [], array $field = ['*'])
    {
        return $this->orderGoodsService->getOrderGoodsList($where, $field);
    }
    /**
     * 生成订单号
     * @param $shop_id
     * @return string
     */
    public static function generateOrderNo(int $shop_id)
    {
        $lsy_shop_no = ShopService::getInfoByShopId($shop_id,['lsy_shop_no'])['lsy_shop_no'];
        $orderNo = '';
        while (true) {
            $orderNo = env('PLATFORMORDERNO') . "XP" . date('YmdHis') . mt_rand(100000, 999999) . self::random_keys(3) . $lsy_shop_no;
            $orderId = OrderModel::query()->where(["order_no" => $orderNo])->value('order_no');
            if (!$orderId) {
                break;
            }
        }
        return $orderNo;
    }
    /**
     * 生成随机字符串
     * @param int $length
     * @return string
     */
    public static function random_keys(int $length)
    {
        $output = '';
        for ($a = 0; $a < $length; $a++) {
            $output .= chr(mt_rand(65, 90));  //生成php随机数 chr(rand(97,122))
        }
        return $output;
    }

    /**
     * 获取未删除下架商品id
     * @param array $goodsIds
     * @param int $shop_id
     * @return array
     */
    public function getGoodsIds(array $goodsIds, int $shop_id)
    {
        $goods = GoodsModel::query()
            ->whereIn('id', $goodsIds)
            ->where(['is_deleted' => 0, 'status' => 1])
            ->whereRaw('!FIND_IN_SET(?,shop_ids)', [$shop_id])
            ->pluck('id');
        return $goods?$goods->toArray():[];
    }
    /**
     * 获取会员总消费
     * @param int $mid
     * @return int|mixed
     */
    public function getMemberTotalPayment(int $mid)
    {
        return OrderModel::query()->where([
            ['mid', '=', $mid],
            ['is_pay', '=', Stakeholder::ORDER_PAID],
            ['status', '!=', Stakeholder::ORDER_REFUNDED]
        ])->sum('total_price');
    }

    /**
     * @param string $date
     * @return string
     * @author ran
     * @date 2021-03-25 15:57
     * mailbox 466180170@qq.com
     */
    public static function get_week( string $date)
    {
        $number_wk = date("w", strtotime($date));
        $weekArr = array("周日", "周一", "周二", "周三", "周四", "周五", "周六");
        return $weekArr[$number_wk] . ' ' . date('m-d', strtotime($date));
    }

    /**
     * @param int $day
     * @param string $time
     * @param string $format
     * @return array
     * @author ran
     * @date 2021-03-25 15:57
     * mailbox 466180170@qq.com
     */
    public  static function get_weeks( int $day, string $time = '', string $format='Y-m-d')
    {
        $time = $time != '' ? $time : time();
        $date = [];
        for ($i=1; $i<=$day; $i++){
            $num = $day-$i;
            $date[$i] = date($format ,strtotime( $num .' days', $time));
        }
        $times=[];
        foreach($date as $key=>$value){
            $times[]=self::get_week($value);
        }
        return $times;
    }
    /**
     * 获取时间段数组["15:00-16:00","16:00-17:00","17:00-18:00","18:00-19:00"]
     * @param $start
     * @param $end
     * @return array
     */
    public static function prTimes(string $start = '07:00', string $end = '24:00'){
        $dt_start = strtotime($start);
        $dt_end = strtotime($end);
        $arr = [];
        $tmp = [];
        while ($dt_start <= $dt_end){
            array_push($arr, date('H:00',$dt_start));
            $dt_start = strtotime('+1 hours',$dt_start);
        }
        for($i = 0;$i < count($arr); $i++){
            if($i+1 == count($arr)) break;
            $tmp[$i]['date'] = $arr[$i].'-'.$arr[$i+1];
        }

        return $tmp;
    }

    /**
     * @param int $shop_id
     * @param int $mid
     * @return string
     * @author ran
     * @date 2021-03-29 13:02
     * mailbox 466180170@qq.com
     */
    public function getCodeNum(int $shop_id, int $mid)
    {
        $time = date('s');
        $_shop_no = ShopModel::where(['shop_id' => $shop_id])->value('shop_no');
        $shop_no = str_shuffle((string)$_shop_no);
        return $mid . $shop_no . $time;
    }
    /**
     * 获取会员已购买秒杀商品数量
     * @param int $mid
     * @param array $actGoodsId
     * @return \Hyperf\Utils\Collection
     * @author ran
     * @date 2021-03-29 12:44
     * mailbox 466180170@qq.com
     */
    public function getPaidSecKillGoodsNum(int $mid, array $actGoodsId){
        return OrderModel::query()
            ->from('store_order as order')
            ->leftJoin('store_order_goods as og', 'order.order_no', '=', 'og.order_no')
            ->selectRaw('og.activity_goods_id,if(og.is_refund_status=0, og.number, (og.number-og.refund_number-og.shop_refund_number)) as paid_num')
            ->where(['order.mid' => $mid, 'order.is_pay' => Stakeholder::ORDER_PAID])
            ->whereIn('og.activity_goods_id', $actGoodsId)
            ->pluck('paid_num', 'activity_goods_id');
    }

    /**
     * 次日达用户意向提货时间
     * @param array $shopInfo
     * @param string $goods_pick_time
     * @return array
     * @author ran
     * @date 2021-04-08 15:56
     * mailbox 466180170@qq.com
     */
    protected function getCommonOverNightCustomerPickTime(array $shopInfo, string $goods_pick_time)
    {
        $currentTime = date('H:i:s');
        $cut_off_time = $this->systemService->getSystemInfo(['name' => 'cut_off_time']);
        $_pick_date_config =  $this->systemService->getSystemInfo(['name' => 'pick_date_config']);
        $pick_date_config = explode(',', $_pick_date_config);
        $pick_date_arr = [];
        foreach ($pick_date_config as $v) {
            $timeArr = explode('-', $v);
            if ($timeArr[1] > $goods_pick_time && $timeArr[1] < $shopInfo['end_time']) {
                $pick_date_arr[] = $v;
            }
        }
        $week = self::get_week('+1 days');
        if ($currentTime > $cut_off_time) {
            $week = self::get_week('+2 days');
        }
        return ['week' => [$week], 'pick_date' => $pick_date_arr];
    }

    /**
     * 创建小程序商城订单服务 利用事件机制进行解耦
     * @param $order
     * @param $activityGoodsInfo
     * @param $userInfo
     * @param $params
     * @param array $insideParams
     * @return array
     * @author ran
     * @date 2021-03-29 13:11
     * mailbox 466180170@qq.com
     */
    protected function createCommonShopOrderInfo(array $userInfo,array $orderInfoCollection,array $cartGoodsList,array $params,array $insideOrder,array $insideCallParams=[]){
        $shopStatus =$this->shop->findFirstValue('status',['shop_id'=>$params['shop_id']]);
        switch ($shopStatus){
            case Stakeholder::SHOP_STATUS_0:
                return $this->error(ErrorCode::SHOP_STATUS_NO_OPEN);
            case Stakeholder::SHOP_STATUS_2:
                return $this->error(ErrorCode::SHOP_STATUS_CLOSE);
        }
        if(empty($cartGoodsList)) return $this->error(ErrorCode::CART_NULL);
        foreach ($cartGoodsList as $goods){
            if($goods['price_selling']<=0){
                return $this->error(ErrorCode::ORDER_PRICE_ERROR,$goods['title'].ErrorCode::getMessage(ErrorCode::ORDER_PRICE_ERROR));
            }
            if($goods['number_stock']<=0){
                return $this->error(ErrorCode::ORDER_GOODS_STOCK_ERROR,$goods['title'].ErrorCode::getMessage(ErrorCode::ORDER_GOODS_STOCK_ERROR));
            }
        }
        $orderNo = self::generateOrderNo((int)$params['shop_id']);
        $orderSerialNum =self::getToDayOrderSerialNumByShopId((int)$params['shop_id']);
        $writeOffCode =Random::character(8);
        $order=array_merge($orderInfoCollection,$insideOrder,$insideCallParams);
        $this->eventDispatcher->dispatch(new CreateShopOrder($orderNo,$orderSerialNum,$writeOffCode,$order,$cartGoodsList,$userInfo,$params));
        return $this->success(['order_no'=>$orderNo]);
    }
    /**
     * 创建小程序活动订单服务 利用事件机制进行解耦
     * @param $order
     * @param $activityGoodsInfo
     * @param $userInfo
     * @param $params
     * @param array $insideParams
     * @return array
     * @author ran
     * @date 2021-03-29 13:11
     * mailbox 466180170@qq.com
     */
    protected function createCommonActivityOrderInfo(array $userInfo,array $insideOrder,array $activityGoodsInfo,array $activityInfo,array $params,array $insideCallParams=[]){
        $shopStatus =$this->shop->findFirstValue('status',['shop_id'=>$params['shop_id']]);
        if($shopStatus!=Stakeholder::SHOP_STATUS_1)return $this->error(ErrorCode::SHOP_STATUS_CLOSE);
        if($activityInfo['status']!=Stakeholder::ACTIVITY_OPEN_STATUS) return ['code' => ErrorCode::ACTIVITY_NOT_IN_HAND];
        if(!in_array($params['shop_id'],explode(',',$activityInfo['shop_ids']))) return ['code' => ErrorCode::ACTIVITY_SHOP_PART_NOT_IN];
        $order_goods_num=$params['number']??1;
        $activity_price_selling=bcmul($activityGoodsInfo['activity_price_selling'],100);
        if ($activity_price_selling <= 0) return $this->error(ErrorCode::SHOP_MONEY_ERROR);
        if ($activityGoodsInfo['activity_number_stock'] <= 0 || $order_goods_num > $activityGoodsInfo['activity_number_stock']) return $this->error(ErrorCode::ACTIVITY_GOODS_UNDER_STOCK);
        $goods_price=bcdiv(bcmul((int)$activity_price_selling,(int)$order_goods_num),100,2);
        $orderCommission= $activityGoodsInfo['commission']?bcmul((string)$order_goods_num, (string)$activityGoodsInfo['commission'], 2):0.00;
        $order_no = self::generateOrderNo((int)$params['shop_id']);
        $order=[
            'order_no'=>$order_no,
            'deal_type'=>self::ORDER_DEAL_TYPE_2,
            'order_goods_num'=>(int)$order_goods_num,
            'goods_price'=>$goods_price,
            'activity_type'=>$insideOrder['activity_type'],
            'total_price'=>$goods_price,
            'order_type'=>$insideOrder['order_type'],
            'order_source'=>self::ORDER_SOURCE_1,
            'order_type_status'=>self::ORDER_TYPE_STATUS_2,
            'appointment_date'=>self::getPickOrderAppointmentDate((string)$params['appointment_time']),
            'order_commission'=>$orderCommission,
            'platform_type'=>$insideOrder['platform_type'],
            'free_num'=>$insideCallParams['free_num'],
            'free_step'=>$insideCallParams['free_step'],
        ];
        $this->eventDispatcher->dispatch(new CreateActivityOrder($order,$activityGoodsInfo,$userInfo,$params));
        return $this->success(['order_no'=>$order_no]);
    }

    /**
     * 获取次日达商品公共服务
     * @param int $shop_id
     * @param int $mid
     * @param array $needExceptKey
     * @param array $needActivityExceptKey
     * @param array $shopInfo
     * @return array
     * @author ran
     * @date 2021-04-12 16:40
     * mailbox 466180170@qq.com
     */
    public function getCommonOverNightConfirmOrderGoodsCollection(int $shop_id,int $platform_type,int $mid,array $needExceptKey=[],array $needActivityExceptKey=[],array $shopInfo=[],$entrust_order_id)
    {
        $ptgoods=$activityGoods=[];
        switch ($platform_type){
            case Stakeholder::ORDER_PLATFORM_TYPE_1:
                $ptgoods =$this->cartMiniService->getResourceOverNightArriveCartGoodsList($shop_id,$mid);
                $activityGoods =$this->cartMiniService->getResourceOverNightArriveCartActivityGoodsList($shop_id,$mid);
                break;
            case Stakeholder::ORDER_PLATFORM_TYPE_2:
                break;
            case Stakeholder::ORDER_PLATFORM_TYPE_3:
                $ptgoods =$this->entrustMiniService->getResourceMiniEntrustGoodsList($entrust_order_id);
                break;
        }
        $goodsCollection=$this->getCommonConfirmOrderGoodsCollection($ptgoods,$shopInfo,$needExceptKey);
        $activityGoodscollection=$this->getCommonConfirmOrderActivityGoodsCollection($activityGoods,$needActivityExceptKey);
        $orderGoodsList =array_merge($goodsCollection['goods'],$activityGoodscollection['activityGoods']);
        $orderGoodsShelfOff=array_merge($goodsCollection['goodsShelfOff'],$activityGoodscollection['goodsShelfOff']);
        $orderGoodsStockOut=array_merge($goodsCollection['goodsStockOut'],$activityGoodscollection['goodsStockOut']);
        $orderPickTime =$goodsCollection['pickTime'];
        return compact("orderGoodsList","orderGoodsShelfOff","orderGoodsStockOut","orderPickTime");
    }

    /**
     * 获取商城订单公共服务
     * @param array $cartGoodsList
     * @return array
     * @author ran
     * @date 2021-04-14 14:43
     * mailbox 466180170@qq.com
     */
    protected function getCommonShopCouponOrderCollectionByCartGoods(array $cartGoodsList){
           $orderGoodsMoney =$orderDeductMoney=$orderFreightDeductMoney=$commission=$orderFreightPrice=0.00;
           $orderCouponStatus = $orderGoodsNumber =$orderType=0;
           $couponInfo=$couponFreightInfo='';
           foreach ($cartGoodsList as $goods) {
               switch ($goods['group_id']){
                   case Stakeholder::GROUP_ID_O:
                       $orderType = self::ORDER_TYPE_8;
                       break;
                   case Stakeholder::GROUP_ID_4:
                       $orderType = self::ORDER_TYPE_9;
                       break;
               }
               $orderGoodsMoney += bcmul((string)$goods['cart_goods_number'], (string)($goods['price_selling']*100), 2);
               $commission +=$goods['commission']? bcmul((string)$goods['cart_goods_number'], (string)($goods['commission']*100), 2):0;
               $orderGoodsNumber += $goods['cart_goods_number'];
           }
           if (!empty($param['coupon'])) {
               if (empty($param['payKey'])) return $this->error(ErrorCode::ORDER_COUPON_PAYKEY_ERROR);
               $coupon = json_decode($param['coupon'], true);
               $orderDeductMoney = (float) array_sum(array_column($coupon, 'deductMoney'));
               $couponInfo = json_encode(['payKey' => $param['payKey'], 'coupon' => $param['coupon']]);
               $orderCouponStatus = 1;
               $orderGoodsMoney = bcsub((string)$orderGoodsMoney, (string)$orderDeductMoney, 2);
           }
           return compact("orderType","orderGoodsMoney","commission","orderGoodsNumber","orderCouponStatus","couponInfo","orderDeductMoney","orderFreightPrice","orderFreightDeductMoney","couponFreightInfo");
    }

    /**
     * 获取商城确认订单信息公共服务
     * @param array $orderGoodsList
     * @return array
     * @author ran
     * @date 2021-04-20 15:20
     * mailbox 466180170@qq.com
     */
    protected function getCommonShopConfirmOrderCollectionByGoods(int $shop_id,int $platform_type,array $orderGoodsList,array $shopInfo){
        $goodsTotalMoney = $goodsMarketTotalMoney = $orderGoodsNumber = 0;
        switch ($platform_type){
            case Stakeholder::ORDER_PLATFORM_TYPE_1:
                $shop_id=$params['shop_id'];
                break;
            case Stakeholder::ORDER_PLATFORM_TYPE_2:
                break;
            case Stakeholder::ORDER_PLATFORM_TYPE_3:
                $shop_id=$params['shop_id'];
                break;
        }
        foreach ($orderGoodsList as $key => $value) {
            $goodsMarketTotalMoney += bcmul((string)$value['cart_goods_number'], (string)($value['price_market'] * 100), 2);
            $goodsTotalMoney += bcmul((string)$value['cart_goods_number'], (string)($value['price_selling'] * 100), 2);
            $orderGoodsNumber += $value['cart_goods_number'];
        }
        return [
            'orderShopInfo' => $shopInfo,
            'orderPickTime' => $orderGoodsCollection['orderPickTime'],
            'orderGoodsList' =>$orderGoodsList,
            'orderPayTotalMoney' =>$goodsTotalMoney,
            'orderMarketTotalMoney' =>$goodsMarketTotalMoney,
            'orderGoodsNumber' =>$orderGoodsNumber,
            'orderDiscountMoney' =>$goodsMarketTotalMoney,
            'orderGoodsShelfOff' => $orderGoodsCollection['orderGoodsShelfOff'],
            'orderGoodsStockOut' =>$orderGoodsCollection['orderGoodsStockOut']
        ];
    }

    /**
     * 处理确认订单活动商品集合数据
     * @param array $Acgoods
     * @param array $needExceptKey
     * @return array
     * @author ran
     * @date 2021-04-08 14:23
     * mailbox 466180170@qq.com
     * // 商品优先下架活动下架结束 库存不足
     */
    public function getCommonConfirmOrderActivityGoodsCollection(array $activityGoods,array $needExceptKey=[]){
        $goodsShelfOff=$goodsStockOut=[];
        foreach($activityGoods as $key=>$value){
            switch ($value['group_id']){
                case Stakeholder::GROUP_ID_4:
                    if($value['activity_status']==Stakeholder::ACTIVITY_DISABLE_STATUS || $value['end_date']<date('Y-m-d H:i:s')){
                        $goodsShelfOff[] = $value['title'];
                        unset($activityGoods[$key]);
                    }
                    break;
            }
            if(!isset($goodsShelfOff)){
                if($value['cart_goods_number']>$value['number_stock']){
                    $goodsStockOut[] = $value['title'];
                    unset($activityGoods[$key]);
                }
            }
        }
        foreach($activityGoods as $key=>$value){
            $pt_self_num = self::getCommonShopSelfNum($value['id']);
            $ac_self_num = self::getCommonShopSelfNum($value['id'],1);
            $activityGoods[$key]['kz_self_num'] = $ac_self_num;
            $activityGoods[$key]['price_selling'] = $value['activity_price_selling'];
            $activityGoods[$key]['price_market'] = $value['activity_price_market'];
            switch ($value['group_id']){
                case Stakeholder::GROUP_ID_4:
                    if($value['per_can_buy_num']<$value['cart_goods_number']){
                        //原价部分
                        $activityGoods[$key]['kz_self_num'] =$pt_self_num;
                        $activityGoods[$key]['group_id'] =Stakeholder::GROUP_ID_O;
                        $activityGoods[$key]['cart_goods_number'] =$value['cart_goods_number']-$value['per_can_buy_num'];
                        $activityGoods[$key]['price_selling'] = $value['activity_price_market'];
                        $activityGoods[$key]['price_market'] = $value['activity_price_selling'];
                        //秒杀部分
                        $value['kz_self_num']=$ac_self_num;
                        $value['price_selling']=$value['activity_price_selling'];
                        $value['price_market']=$value['activity_price_market'];
                        $value['cart_goods_number']=$value['per_can_buy_num'];
                        array_push($activityGoods,$value);
                    }
                    break;
            }
        }
        $activityGoods=$this->arr->exceptMoreArrKey($activityGoods,$needExceptKey);
        return compact("activityGoods","goodsShelfOff","goodsStockOut");
    }

    /**
     * 处理确认订单商品集合数据
     * @param array $goods
     * @return array
     * @author ran
     * @date 2021-04-06 15:40
     * mailbox 466180170@qq.com
     */
    public function getCommonConfirmOrderGoodsCollection(array $goods,array $shopInfo,array $needExceptKey=[]):array
    {
        $goodsShelfOff=$goodsStockOut=$pickTime=[];
        foreach ($goods as $key=>$value){
            if($value['status']=Stakeholder::GOODS_STATUS_0){
                $goodsShelfOff[] = $value['title'];
                unset($goods[$key]);
                if(!isset($goodsShelfOff)){
                    if($value['cart_goods_number']>$value['number_stock']){
                        $goodsStockOut[] = $value['title'];
                        unset($activityGoods[$key]);
                    }
                }
            }
            $goods[$key]['kz_self_num'] = self::getCommonShopSelfNum($value['id']);
        }
        $goods_pick_time = $goods?max(array_column($goods, 'goods_pick_time')):'';
        if(!empty($shopInfo)) $pickTime=self::getCommonOverNightCustomerPickTime($shopInfo,$goods_pick_time);
        $goods=$this->arr->exceptMoreArrKey($goods,$needExceptKey);
        return compact("goods","goodsShelfOff","goodsStockOut","pickTime");
    }
    /**
     * 获取平台货架号
     * type 0 普通品 1 秒杀 2限购
     * @param int $goods_id
     * @param object $redis
     * @return string
     */
    public function getCommonShopSelfNum(int $goods_id,int $type=0)
    {
        $key = $type==1? (string)$goods_id.'ms':( $type==2?(string)$goods_id.'xg':(string)$goods_id);
        if(!$kz_self_num = $this->resourceRedis->hGet(self::SHOP_GOODS_SHELVE, $key)){
            $kz_self_num = Random::makeSelfNum();
            $this->resourceRedis->hSet(self::SHOP_GOODS_SHELVE, $key, $kz_self_num);
        }
        return $kz_self_num;
    }
    /**
     * 店铺当日下单序列数
     * @param $shopId
     * @return int
     */
    public static function getToDayOrderSerialNumByShopId(int $shopId)
    {
        $todayStart = date('Y-m-d', time());
        $orderCount = OrderModel::query()->where('create_at', '>', $todayStart)->where(['shop_id' => $shopId])->count();
        return $orderCount + 1;
    }
    /**
     * 获取用户自提时间转换
     * @param $shopId
     * @return int
     */
    public  function getPickOrderAppointmentDate(string $appointmentTime)
    {
        preg_match("/[0-9]{1,}-[0-9]{1,}\s[0-9]{1,}:[0-9]{1,}/",$appointmentTime,$match);
        return $match? date('Y-').$match[0]:'';
    }

    /**
     * 延时队列取消订单公用方法
     * @param string $orderNo
     * @author ran
     * @date 2021-03-26 15:28
     * mailbox 466180170@qq.com
     */
    public function cancelCommonOrder(string $orderNo){

         $this->orderDriver->push(new CancelOrderJob(['order_no' => $orderNo]), self::CANCEL_ORDER_SECOND);
    }
    /**
     * 记录日志
     * $type=0及时达 $type =1次日达
     * @param string $event
     * @param array $param
     * @param int $type
     * @param string $response
     * @return bool
     */
    public function createCommonOrderLog(string $event, array $param, int $order_type, string $response)
    {
        $data = ['type' => 2, 'data' => ['event' => $event, 'params' => json_encode($param), 'order_type' => $order_type, 'response' => $response, 'created_at' => date('Y-m-d H:i:s')]];
        $this->driverLog->push(new LogJob($data), 1);
    }
    /**
     * 删除购物车
     * @param $cartIds
     * @param $mid
     */
    public function deleteCart($cartIds,$mid)
    {
        $this->cartService->deleteCartById($cartIds,$mid);

    }
}